package com.nan.gbd.library.codec;

import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.nan.gbd.R;
import com.nan.gbd.library.JNIBridge;
import com.nan.gbd.library.StatusCallback;
import com.nan.gbd.library.codec.configuration.AudioConfiguration;
import com.nan.gbd.library.codec.configuration.CameraConfiguration;
import com.nan.gbd.library.codec.configuration.Configuration;
import com.nan.gbd.library.codec.configuration.VideoConfiguration;
import com.nan.gbd.library.codec.livecodec.MediaLiveManager;
import com.nan.gbd.library.codec.recordcodec.MediaRecordManager;
import com.nan.gbd.library.codec.surface.CameraSurfaceView;
import com.nan.gbd.library.codec.surface.OnCameraListener;
import com.nan.gbd.library.codec.surface.VideoEncodeRender;
import com.nan.gbd.library.codec.utils.WeakHandler;
import com.nan.gbd.library.extractor.SimplePlayer;
import com.nan.gbd.library.sip.GBEvent;
import com.nan.gbd.library.utils.AccountConfig;
import com.nan.gbd.library.utils.Logger;
import com.nan.gbd.library.utils.MainThreadManager;
import com.nan.gbd.library.utils.usage.Usage;
import com.nan.gbd.library.utils.usage.UsageUtil;

import java.io.File;


/**
 * @author NanGBD
 * @date 2020.6.8
 */
public class GBMediaNative extends BaseGBMedia implements FinishCallback {
    private MediaLiveManager mediaLiveManager;
    private MediaRecordManager mediaRecordManager;
    private SimplePlayer simplePlayer;
    private Runnable mCurTask = null;
    private WeakHandler mHandler = new WeakHandler(Looper.getMainLooper());
    private static GBMediaNative mInstance;


    public static synchronized GBMediaNative getInstance() {
        if (mInstance == null) {
            mInstance = new GBMediaNative();
        }
        return mInstance;
    }

    public GBMediaNative() {
        Logger.e("初始化sdk消息接收器");
        JNIBridge.setStatusCallback(this);
    }


    public synchronized int initMuxer(VideoConfiguration videoConfig) {
        Logger.e("startMuxer pid:" + Thread.currentThread().getId());
        CameraConfiguration configuration = CameraConfiguration.createDefault();
        return JNIBridge.nanInitMuxer(
                Configuration.get().getRecordPath(),
                "",
                Configuration.get().getMaxRecordFileLength(),
                mEnableVideo,
                mEnableAudio,
                vencodec,
                configuration.orientation == CameraConfiguration.Orientation.LANDSCAPE ? 1 : 0,
                configuration.width,
                configuration.height,
                videoConfig.width,
                videoConfig.height,
                videoConfig.fps,
                videoConfig.ifi,
                videoConfig.maxBps,
                bitrateMode,
                profile,
                audioFrameLen,
                mThreadNum,
                mAvQueueSize,
                mVideoBitrateFactor,
                mVideoBitrateAdjustPeriod,
                mStreamStatPeriod
        );
    }

    @Override
    protected void startPushMedia(int key, byte[] param) {
        if (isRunning) {
            Logger.e("已经有任务正在执行中,请等待执行....");
            return;
        }
        if (key == 101) {
            startLive();
        }
        if (key == 102) {
            startPlayBack(param);
        }
        if (key == 103) {
            startDownload(param);
        }
    }

    @Override
    protected void stopPushMedia() {
        stopPush();
    }

    @Override
    protected void startRecordMedia() {
        startRecord();
    }

    @Override
    protected void stopRecordMedia() {
        stopRecord();
    }

    @Override
    protected void playMediaControl(int key, byte[] param) {
        playControl(key, param);
    }

    @Override
    protected void startPlayVoiceMedia(int key) {
        startVoice(key);
    }

    @Override
    protected void endPlayVoiceMedia(int key) {
        endVoice(key);
    }

    @Override
    protected void playVoiceMediaData(int key, byte[] param) {
        playVoiceData(key, param);
    }

    /**
     * 初始化相机
     */
//    private void initCameraPreView() {
//        Log.e("YJQ", "start camera preview....................");
//
//        params = new WindowManager.LayoutParams();
//        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
//        params.format = PixelFormat.RGBA_8888;
//        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
//                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
//
//        params.width = 90;
//        params.height = 160;
//        params.gravity = Gravity.TOP | Gravity.RIGHT;
//        params.x = 0;
//        params.y = 10;
//        mFloatView = new LinearLayout(mContext);
//        cameraSurfaceView = new CameraSurfaceView(mContext);
//        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
//        mFloatView.addView(cameraSurfaceView, layoutParams);
//        mWindowManager.addView(mFloatView, params);
//        Log.e("YJQ", "start camera: " + System.currentTimeMillis());
//        cameraSurfaceView.setmOnPreviewListener(onCameraListener);
//    }
    private void initCameraPreView() {
        if (cameraSurfaceView != null) {
            return;
        }
        Log.e("YJQ", "start camera preview....................");

        params = new WindowManager.LayoutParams();
        int type = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_PHONE;

        params.type = type;
        params.format = PixelFormat.RGBA_8888;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
        params.width = 128;
        params.height = 72;
        params.gravity = Gravity.TOP | Gravity.END;
        params.x = 0;
        params.y = 10;

        mFloatView = new FrameLayout(mContext);
        FrameLayout.LayoutParams layoutParams =
                new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                        FrameLayout.LayoutParams.MATCH_PARENT);
        cameraSurfaceView = new CameraSurfaceView(mContext);
        mFloatView.addView(cameraSurfaceView, layoutParams);
        // 设置 SurfaceView 参数
        mWindowManager.addView(mFloatView, params);
        Log.e("YJQ", "start camera: " + System.currentTimeMillis());
        cameraSurfaceView.setmOnPreviewListener(onCameraListener);

//        LayoutInflater inflater = LayoutInflater.from(mContext);
//        mFloatView = inflater.inflate(R.layout.layout_video_preview, null);
//        mWindowManager.addView(mFloatView, params);
//
//        Log.e("YJQ", "start camera: " + System.currentTimeMillis());
//
//        cameraSurfaceView = mFloatView.findViewById(R.id.render_video_view);
//        cameraSurfaceView.setmOnPreviewListener(onCameraListener);


    }

    private int dpToPx(int dp) {
        float density = mContext.getResources().getDisplayMetrics().density;
        return Math.round(dp * density);
    }

    OnCameraListener onCameraListener = new OnCameraListener() {
        @Override
        public void openCameraSuccess(int mPreviewWidth, int mPreviewHeight) {
            Logger.e("摄像头预览宽x高:" + mPreviewWidth + "x" + mPreviewHeight);
            processAccumulatedTask();
        }

        @Override
        public void openCameraFaile() {
            setReleasePreviewTask();
        }
    };


    /**
     * 开始推流
     *
     * @return true:成功
     */
    protected synchronized boolean startLive() {
        if (isLiving) {
            Logger.e("已经开始了就不用再次开始");
            return true;
        }
        if (cameraSurfaceView == null) {
            if (mCurTask == null) {
                mCurTask = new Runnable() {
                    @Override
                    public void run() {
                        initLivingImpl();
                    }
                };
            }
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    initCameraPreView();
                }
            });
        }

        return true;
    }

    /**
     * 初始化直播
     */
    private void initLivingImpl() {
        int ret = initMuxer(VideoConfiguration.getLivingConfig());
        if (ret != 0) {
            Logger.e("sdk Muxer初始化失败 error:" + ret);
            Log.w("native", "sdk Muxer初始化失败 error:" + ret);
            return;
        }
        //设置开始标志位
        isLiving = true;
        isRunning = true;
        //开启编码器
        VideoEncodeRender videoEncodeRender = new VideoEncodeRender(mContext, cameraSurfaceView);
        mediaLiveManager = new MediaLiveManager(videoEncodeRender, cameraSurfaceView.getEglContext(), this);
        mediaLiveManager.initMediaCodec();
        mediaLiveManager.initThread();
        mediaLiveManager.startEncode();
        //开启流量统计
        push_start = System.currentTimeMillis();
        startUsage();

        if (helmetVoiceCallBack != null) {
            helmetVoiceCallBack.playLiveVoice();
        }
    }

    private long push_start;
    private long push_end;

    private void startUsage() {
        mHandler.postDelayed(usageRunnable, 60 * 1000);
    }

    Runnable usageRunnable = new Runnable() {
        @Override
        public void run() {
            int uid = UsageUtil.getUidByPackageName(mContext, mContext.getPackageName());
            push_end = System.currentTimeMillis();
            Usage usage = UsageUtil.getApplicationQuerySummary(mContext, push_start, push_end, uid);
            Logger.e("GB28181推流开始时间：" + push_start);
            Logger.e("GB28181推流结束时间：" + push_end);
            Logger.e("当前APP uid：" + uid);
            Logger.e("开启直播过去1分钟流量统计：" + usage.toString());
            startUsage();
        }
    };


    /**
     * 开始回放
     *
     * @param param
     * @return
     */
    protected synchronized boolean startPlayBack(byte[] param) {
        if (isPlayback) {
            Logger.e("已经开始了,不能重复执行");
            return true;
        }
        if (param == null || param.length == 0) {
            Logger.e("参数错误，请重试");
            return false;
        }
        String recordPath = checkFileExists(param);
        if (TextUtils.isEmpty(recordPath)) {
            Logger.e("文件不存在,请检查");
            return false;
        }
        isPlayback = true;
        isRunning = true;
        simplePlayer = new SimplePlayer(recordPath, this, this, false);
        return simplePlayer.play();
    }

    /**
     * 开始下载
     *
     * @param param
     * @return
     */
    protected synchronized boolean startDownload(byte[] param) {
        if (isDownload) {
            Logger.e("已经开始了,不能重复执行");
            return true;
        }
        if (param == null || param.length == 0) {
            Logger.e("参数错误，请重试");
            return false;
        }
        String recordPath = checkFileExists(param);
        if (TextUtils.isEmpty(recordPath)) {
            Logger.e("文件不存在,请检查");
            return false;
        }
        isDownload = true;
        isRunning = true;
        simplePlayer = new SimplePlayer(recordPath, this, this, true);
        return simplePlayer.play();
    }

    private String checkFileExists(byte[] param) {
        if (param == null || param.length == 0)
            return null;
        String recordPath = new String(param);
        File file = new File(recordPath);
        if (!file.exists()) {
            return null;
        }
        return recordPath;
    }

    /**
     * 停止推流
     *
     * @return true:成功
     */
    public synchronized boolean stopPush() {
        Logger.e("停止推流 pid:" + Thread.currentThread().getId());
        if (!isRunning) {
            Logger.e("已停止推流,无需再次停止");
            return true;
        }
        if (isPlayback) {
            isStopFormServer = true;
            simplePlayer.stop();
            return true;
        }
        if (isDownload) {
            isStopFormServer = true;
            simplePlayer.stop();
            return true;
        }
        if (isLiving) {
            mediaLiveManager.stop();
            return true;
        }
        return false;
    }


    /**
     * 开始录制
     */
    public synchronized boolean startRecord() {
        boolean check = AccountConfig.getInstance().checkStorage();
        if (check) Logger.e("检查存储空间完成,符合存储条件");
        else return false;

        if (isRunning) {
            Logger.e("已经有任务正在执行中....");
            return false;
        }
        if (cameraSurfaceView == null) {
            if (mCurTask == null) {
                mCurTask = new Runnable() {
                    @Override
                    public void run() {
                        initRecordingImpl();
                    }
                };
            }
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    initCameraPreView();
                }
            });
        }
        return true;
    }

    /**
     * 初始化录制视频
     */
    private void initRecordingImpl() {
        VideoEncodeRender videoEncodeRender = new VideoEncodeRender(mContext, cameraSurfaceView);
        mediaRecordManager = new MediaRecordManager(videoEncodeRender, cameraSurfaceView.getEglContext(), this);
        mediaRecordManager.initMediaCodec();
        mediaRecordManager.initThread();
        mediaRecordManager.start();
        isRecording = true;
        isRunning = true;
        if (helmetVoiceCallBack != null) {
            helmetVoiceCallBack.playRemindVoice();
        }
    }

    /**
     * 停止录制
     */
    public synchronized boolean stopRecord() {
        if (!isRecording) {
            Logger.e("已经停止了就不用再次停止");
            return true;
        }
        mediaRecordManager.stop();
        return true;
    }

    /**
     * 历史回放控制
     *
     * @param key
     * @param param
     * @return
     */
    private boolean playControl(int key, byte[] param) {
        /*播放/快放/慢放*/
        if (key == 1001) {
            if (param != null && param.length != 0) {
                String value = new String(param);
                if (value.contains("Scale")) {

                }
                if (value.contains("range_start") && value.contains("range_end")) {

                }
                if (value.contains("Play")) {
                    simplePlayer.resume();
                }
                return true;
            }
            return false;
        }
        /*暂停*/
        if (key == 1002) {
            simplePlayer.pause();
            return true;
        }
        /*停止*/
        if (key == 1003) {
            simplePlayer.stop();
            return true;
        }
        return false;
    }

    /**
     * 开始任务
     */
    private void processAccumulatedTask() {
        if (mCurTask != null) {
            mHandler.post(mCurTask);
        }
    }


    @Override
    public void onFinished(int type) {
        //直播停止--相关资源释放完成
        if (type == 1) {
            destroyLiving();
            Logger.e("living status stop finish");
        }
        //历史回放--相关资源释放完成
        if (type == 2) {
            Logger.e("playback status stop finish");
            //重新播放
            destroyPlayback();
        }
        //下载--相关资源释放完成
        if (type == 4) {
            Logger.e("download status stop finish");
            destroyDownload();
        }
        //本地录制--相关资源释放完成
        if (type == 3) {
            Logger.e("record status stop finish");
            destroyRecording();
        }
    }

    private boolean destroyPlayback() {
        simplePlayer = null;
        isPlayback = false;
        isRunning = false;
        if (!isStopFormServer) {
            JNIBridge.nanPlayerEnd();
        }
        isStopFormServer = false;
        return true;
    }

    private boolean destroyDownload() {
        simplePlayer = null;
        isDownload = false;
        isRunning = false;
        if (!isStopFormServer) {
            JNIBridge.nanPlayerEnd();
            isStopFormServer = false;
        }
        return true;
    }

    private boolean destroyLiving() {
        mediaLiveManager = null;
        isLiving = false;
        isRunning = false;
        setReleasePreviewTask();
        if (helmetVoiceCallBack != null) {
            helmetVoiceCallBack.stopLiveVoice();
        }
        mHandler.removeCallbacksAndMessages(null);
        return true;
    }

    private boolean destroyRecording() {
        mediaRecordManager = null;
        isRecording = false;
        isRunning = false;
        setReleasePreviewTask();
        //播放停止提示音
        if (helmetVoiceCallBack != null) {
            helmetVoiceCallBack.stopRemindVoice();
        }
        mHandler.removeCallbacksAndMessages(null);
        return true;
    }

    /**
     * 停止相机预览,销毁悬浮窗
     */
    private void setReleasePreviewTask() {
        mHandler.post(releasePreviewRunnable);
    }

    private Runnable releasePreviewRunnable = new Runnable() {
        @Override
        public void run() {
            if (mWindowManager != null) {
                mWindowManager.removeViewImmediate(mFloatView);
                mFloatView.removeView(cameraSurfaceView);
            }
            if (cameraSurfaceView != null) {
                cameraSurfaceView.releaseCamera();
                cameraSurfaceView = null;
                mCurTask = null;
            }
        }
    };
}
